package a5.grammar.interfaces;

import a5.common.ProgramCursor;
import a5.environment.Environment;

/**
 * A Grammar is a loose composition of {@link a5.grammar.interfaces.Production Productions} which may be 
 * used to parse and/or interpret a {@code String} purportedly in the grammar. In addition to providing
 * an interface for interpreting and parsing strings, a class implementing this interface must also
 * provide a mechanism for fetching productions. Productions are easily added to a grammar by 
 * adding the {@link a5.grammar.interfaces.Grammar Grammar} class to the list of classes in the 
 * {@link a5.grammar.annotations.Grammar @Grammar} annotation and implementing the Production interface.
 * 
 * @author Jason Campos
 * @version Assignment 5, CS 152 (Programming Paradigms) Fall 2012, Jeffrey Smith
 */
public interface Grammar {
	/*
	 * (non-javadoc)
	 * Implementation details left to implementing class. Provide a mechanism for fetching productions.
	 */
	public <E extends Production> E getProduction(Class<E> production);
	
	/**
	 * Applies the grammar {@link a5.gammar.interfaces.Production Productions} to the program tokens
	 * of the {@link a5.common.ProgramCursor cursor} using the variable and function scoping policies
	 * defined by the argument {@link a5.environment.Environment Environment}.
	 * 
	 * @param environment
	 * The {@link a5.environment.Environment Environment} responsible for variable and function maintenance
	 * and scoping. 
	 * 
	 * @param cursor
	 * The {@link a5.common.ProgramCursor ProgramCursor} which contains the {@link a5.common.Token Tokens} 
	 * of the program being interpreted.
	 * 
	 * @return
	 * The interpretation result as a {@code String}
	 */
	public String interpret(Environment environment, ProgramCursor cursor);
	
	/**
	 * Specifies the parser with which to parse a program purportedly of this grammar.
	 * 
	 * @param cursor
	 * The {@link a5.common.ProgramCursor ProgramCursor} which contains the {@link a5.common.Token Tokens} 
	 * of the program being interpreted.
	 * 
	 * @return
	 * The parse result as a {@code String} 
	 */
	public String parse(ProgramCursor cursor);
}
